package com.sharp.wechat.service.account;

import com.sharp.authorization.constants.token.TokenItemConst;
import com.sharp.authorization.service.login.LoginService;
import com.sharp.authorization.service.token.TokenService;
import com.sharp.authorization.service.user.UserInfoService;
import com.sharp.authorization.vo.login.LoginRes;
import com.sharp.authorization.vo.user.RealNameReq;
import com.sharp.kernel.constant.CommonConst;
import com.sharp.kernel.constant.err.ErrCodeSys;
import com.sharp.framework.service.cache.FrameCacheService;
import com.sharp.kernel.utils.ReflectionUtil;
import com.sharp.kernel.validate.Validator;
import com.sharp.wechat.constant.WechatConst;
import com.sharp.wechat.constant.WechatTokenItem;
import com.sharp.wechat.dao.entity.MmOpenidMap;
import com.sharp.wechat.dao.repository.MmOpenidMapService;
import com.sharp.wechat.po.ocr.IdCardOcrReq;
import com.sharp.wechat.po.ocr.IdCardOcrRes;
import com.sharp.wechat.service.ocr.WechatOcrService;
import com.sharp.wechat.vo.auth.AuthRealNameReq;
import com.sharp.wechat.vo.auth.AuthRes;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;

/**
 * Title: AccountService
 * Description: Copyright: Copyright (c) 2019 Company: BHFAE
 *
 * @author Sharp
 * @date 2020/6/19 15:43
 */
@Slf4j
@Service
public class SyncAccountService {
    @Resource
    private LoginService loginService;
    @Resource
    private MmOpenidMapService mmOpenidMapService;
    @Resource
    private WechatOcrService wechatOcrService;
    @Resource
    private UserInfoService userInfoService;
    @Resource
    private TokenService tokenService;
    @Resource
    private FrameCacheService frameCacheService;

    @Transactional(rollbackFor = Exception.class)
    public LoginRes loginOrReg(String openId, String unionId, String nickName, String avatar) {
        MmOpenidMap map = mmOpenidMapService.getOpenidMapByOpenId(openId);
        if (map == null) {
            map = buildMmOpenidMap(openId, unionId, nickName, avatar);
            mmOpenidMapService.insertSelective(map);
        }
        LoginRes res;
        if (StringUtils.isNotBlank(map.getPhone())) {
            res = loginService.loginOrReg(map.getPhone());
            userInfoService.setAvatar(res.getCustomerNumber(), avatar);
        } else if (StringUtils.isNotBlank(map.getUnionId())) {
            res = loginService.loginOrRegByWechatUnionId(map.getUnionId(), map.getNickName());
            userInfoService.setAvatar(res.getCustomerNumber(), avatar);
        } else {
            res = buildGuestLoginRes(map.getOpenId(), map.getNickName());
        }
        return res;
    }

    private MmOpenidMap buildMmOpenidMap(String openId, String unionId, String nickName, String avatar) {
        MmOpenidMap map = new MmOpenidMap();
        map.setOpenId(openId);
        map.setAvatar(avatar);
        boolean openIdAsAccount = true;
        try {
            String openIdAccount = frameCacheService.getParamValueAvail(WechatConst.WECHAT_OPENID_ACCOUNT);
            openIdAsAccount = StringUtils.equals(openIdAccount, CommonConst.YES);
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (StringUtils.isNotBlank(unionId)) {
            map.setUnionId(unionId);
        } else if (openIdAsAccount) {
            map.setUnionId(openId);
        }
        map.setNickName(nickName);
        return map;
    }

    private LoginRes buildGuestLoginRes(String openId, String nickName) {
        String accessToken = tokenService.buildWechatToken(openId);
        tokenService.putItem(accessToken, TokenItemConst.OPERATOR.name(), openId);
        tokenService.putItem(accessToken, TokenItemConst.NICK_NAME.name(), nickName);
        LoginRes res = new LoginRes();
        res.setCustomerNumber(openId);
        res.setName(nickName);
        res.setAccessToken(accessToken);
        return res;
    }

    @Transactional(rollbackFor = Exception.class)
    public void realName(AuthRealNameReq req) {
        IdCardOcrReq idCardOcrReq = ReflectionUtil.copy(req, IdCardOcrReq.class);
        IdCardOcrRes idCardOcrRes = wechatOcrService.idCardOcr(idCardOcrReq);
        RealNameReq realNameReq = ReflectionUtil.copy(idCardOcrRes, RealNameReq.class);
        userInfoService.realName(realNameReq);
    }

    @Transactional(rollbackFor = Exception.class)
    public AuthRes loginOrRegByPhoneNumber(String phoneNumber) {
        String openId = tokenService.getItem(WechatTokenItem.OPEN_ID.name(), String.class);
        String nickName = tokenService.getItem(TokenItemConst.NICK_NAME.name(), String.class);
        Validator.assertNotBlank(openId, ErrCodeSys.SYS_ERR_MSG, "未检测到微信登录");
        MmOpenidMap map = mmOpenidMapService.getOpenidMapByOpenId(openId);
        Validator.assertNotNull(map, ErrCodeSys.PA_DATA_NOT_EXIST, "微信用户");
        map.setPhone(phoneNumber);
        mmOpenidMapService.updateByPrimaryKeySelective(map);

        LoginRes res = loginService.loginOrRegByWechatPhoneNumber(map.getUnionId(), nickName, phoneNumber);
        userInfoService.setAvatar(res.getCustomerNumber(), map.getAvatar());
        return buildAuthResByToken(res.getAccessToken());
    }

    private AuthRes buildAuthResByToken(String token) {
        AuthRes res = new AuthRes();
        res.setToken(token);
        res.setUserId(tokenService.getItem(token, TokenItemConst.OPERATOR.name(), String.class));
        res.setNickName(tokenService.getItem(token, TokenItemConst.NICK_NAME.name(), String.class));
        res.setHeadImgUrl(tokenService.getItem(token, TokenItemConst.AVATAR.name(), String.class));
        return res;
    }
}
